<template>
  <a-menu
    v-model:open-keys="openedKeys"
    v-model:selectedKeys="selectKeys"
    v-bind="$attrs"
    class="antd-menu"
    @select="onSelect"
    @deselect="onDeselect"
  >
    <sub-menu
      v-for="item of menus"
      :menu="item"
      :fields="fields"
      :popup-class-name="['antd-menu-popup-menu', popupClassName].join(' ')"
      @titleClick="(e) => $emit('titleClick', e)"
    />
  </a-menu>
</template>

<script>
import { ref, computed, watch } from 'vue';
import SubMenu from './sub-menu.vue';

export default {
  name: 'antd-menu',
  components: { SubMenu },
  emits: ['update:modelValue', 'change', 'select', 'deselect', 'titleClick'],
  props: {
    modelValue: { type: Array, default: () => [] },
    openKeys: { type: Array, default: () => [] },
    menus: { type: Array, default: () => [] },
    replaceFields: { type: Object, default: undefined },
    popupClassName: { type: String, default: undefined },
  },
  setup(props, context) {
    const fields = computed(() => {
      const opt = { key: 'key', title: 'title', icon: 'icon', children: 'children' };
      return Object.assign({}, opt, props.replaceFields);
    });
    const openedKeys = ref([]);
    const selectKeys = ref([]);
    const handleSelect = ({ selectedKeys }) => {
      selectKeys.value = selectedKeys;
      context.emit('update:modelValue', selectedKeys);
    };
    const onSelect = ({ item, key, selectedKeys }) => {
      handleSelect({ item, key, selectedKeys });
      setTimeout(() => {
        context.emit('select', { item, key, selectedKeys });
        context.emit('change', { item, key, selectedKeys });
      }, 0);
    };
    const onDeselect = ({ item, key, selectedKeys }) => {
      handleSelect({ item, key, selectedKeys });
      setTimeout(() => {
        context.emit('deselect', { item, key, selectedKeys });
        context.emit('change', { item, key, selectedKeys });
      }, 0);
    };
    watch(
      () => props.modelValue,
      () => {
        selectKeys.value = props.modelValue;
      },
      { immediate: true },
    );
    watch(
      () => props.openKeys,
      () => {
        openedKeys.value = props.openKeys;
      },
      { immediate: true },
    );
    return { fields, openedKeys, selectKeys, onSelect, onDeselect };
  },
};
</script>

<style lang="less">
/* 不要放到 .antd-menu 下, 会影响弹出层的样式 */
.ant-menu-item,
.ant-menu-submenu {
  .ant-menu-title-content {
    .antd-menu-icon {
      height: 1.5em;
      margin-right: 0.5em;
    }
  }
}
</style>
